#include <iostream>
#include "glDisplay.h"
#include "Image.h"
#include "Camera.h"
#include "RenderingSystem.h"
#include "ImpSphereObject.h"
#include "PhongShader.h"
#include "ImpPlaneObject.h"
#include <time.h>
#include <cstdlib>

using namespace std;

int main(int argc, char *argv[])
{
    //Timing
    srand((unsigned)time(0));
    double elapsed;
    time_t start = time(NULL);

    //New image, we will render to this.
    Image rTarget(128, 80);

    //Setting up camera
    Camera rCamera(Vector3(0.5, 0.5, 1.0));





    //Create materials
    Material glass;
    glass.SetColor(Vector3(1.0, 1.0, 1.0));
    glass.SetReflectance(0.1);
    glass.SetTransparancy(0.9);
    glass._RefractiveIndex = 1.6;

    Material blue;
    blue.SetColor(Vector3(0.8, 0.8, 1.0));
    blue.SetReflectance(0.2);
    blue.SetTransparancy(0.0);
    blue._RefractiveIndex = 1.6;

    Material yellow;
    yellow.SetColor(Vector3(1.0, 1.0, 0.4));
    yellow.SetReflectance(0.0);
    yellow.SetTransparancy(0.0);
    yellow._RefractiveIndex = 1.6;

    Material dark;
    dark.SetColor(Vector3(0.2, 0.2, 0.2));
    dark.SetReflectance(0.0);
    dark.SetTransparancy(0.0);
    dark._RefractiveIndex = 1.6;

    Material gray;
    gray.SetColor(Vector3(0.5, 0.5, 0.5));
    gray.SetReflectance(0.0);
    gray.SetTransparancy(0.0);
    gray._RefractiveIndex = 1.6;

    Material red;
    red.SetColor(Vector3(1.0, 0.4, 0.4));
    red.SetReflectance(0.0);
    red.SetTransparancy(0.0);
    red._RefractiveIndex = 1.6;

    Material green;
    green.SetColor(Vector3(0.4, 0.7, 0.4));
    green.SetReflectance(0.0);
    green.SetTransparancy(0.0);
    green._RefractiveIndex = 1.0;

    Material white;
    white.SetColor(Vector3(0.8, 0.8, 0.8));
    white.SetReflectance(0.0);
    white.SetTransparancy(0.0);
    white._RefractiveIndex = 1.0;




    //Define Scene
    SceneStructure rScene;

    LightSource pointSource(Vector3(0.0, 2.0, -7.0));
    pointSource.SetEnergy(7.5);

    ImpSphereObject sphere1(1.0);
    sphere1.SetPosition(Vector3(-1.5, -1.8, -8.0));
    sphere1._sh = new PhongShader();
    sphere1._material = &glass;

    ImpSphereObject sphere2(1.6);
    sphere2.SetPosition(Vector3(1.5, -1.4, -8.0));
    sphere2._sh = new PhongShader();
    sphere2._material = &yellow;

    ImpPlaneObject floor(Vector3(0.0, -3.0, 0.0), Vector3(0.0, 1.0, 0.0));
    floor._sh = new PhongShader();
    floor._material = &gray;

    ImpPlaneObject front_wall(Vector3(0.0, 0.0, -11.0), Vector3(0.0, 0.0, 1.0));
    front_wall._sh = new PhongShader();
    front_wall._material = &white;

    ImpPlaneObject left_wall(Vector3(-3.0, 0.0, 0.0), Vector3(1.0, 0.0, 0.0));
    left_wall._sh = new PhongShader();
    left_wall._material = &blue;

    ImpPlaneObject right_wall(Vector3(3.0, 0.0, 0.0), Vector3(-1.0, 0.0, 0.0));
    right_wall._sh = new PhongShader();
    right_wall._material = &red;

    rScene.AddRenderableObject(sphere1);
    rScene.AddRenderableObject(sphere2);
    rScene.AddRenderableObject(floor);
    rScene.AddRenderableObject(front_wall);
    rScene.AddRenderableObject(left_wall);
    rScene.AddRenderableObject(right_wall);
    rScene.AddLightSource(pointSource);




    //Setup rendering system
    RenderingSystem rEngine;
    rEngine.SetScene(rScene);
    rEngine.NumberOfPhotons_IndirectLighting = 60000;
    rEngine.NumberOfPhotons_Caustics = 100000;
    rEngine.Render(rTarget, rCamera);


    //Cout time elapsed
    time_t finish = time(NULL);
    elapsed = difftime(finish, start);
    std::cout << "Rendering complete ín " << elapsed << " seconds." << std::endl;


    //Create display system
    glDisplay rDisplay(rTarget, argc, argv);
}
